﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text;

namespace ClubWebsite
{
    public partial class Admin : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Only allow the admin to access this page
            if (!Functions.UserIsSiteAdminstrator())
            {
                Response.Redirect("404.aspx");
                return;
            }

            // Check if a scrape should be run
            if (Request.QueryString["ScrapeID"] != null)
            {
                // Get the scrape
                Guid scrapeID;
                if ((Request.QueryString["ScrapeID"].ToLower() == "all") && (Request.QueryString["Done"] != null))
                {
                    // Run the scrapes one at a time
                    int done = int.Parse(Request.QueryString["Done"]);
                    scrapeID = Functions.GetDatabaseDataContext()
                        .Scrapes
                        .OrderBy(s => s.ID)
                        .Skip(done)
                        .Select(s => s.ID)
                        .FirstOrDefault();

                    if (scrapeID == Guid.Empty)
                    {
                        Response.Write("All scrapes are complete.<br />");
                    }
                }
                else
                {
                    try
                    {
                        scrapeID = new Guid(Request.QueryString["ScrapeID"]);
                    }
                    catch
                    {
                        scrapeID = Guid.Empty;
                    }
                }

                // Run the scrape
                if (scrapeID != Guid.Empty)
                {
                    string scrape = Functions.GetDatabaseDataContext()
                        .Scrapes
                        .Where(s => (s.ID == scrapeID) || (scrapeID == Guid.Empty))
                        .Select(s => s.Description)
                        .Single();
                    using (WebService webService = new WebService())
                    {
                        Guid reference = Guid.NewGuid();
                        if (!webService.Login("admin", "", reference))
                        {
                            throw new ApplicationException("Login failed");
                        }
                        Response.Write(String.Format("Running scrape {1} ({0})...",
                            scrapeID,
                            scrape
                            ));
                        try
                        {
                            webService.RunScrape(scrapeID, reference);
                            Response.Write("Complete.<br />");
                        }
                        catch (Exception ex)
                        {
                            Response.Write(String.Format("Failed."
                                + "<br/>  - Message: {0}"
                                + "<br/>  - Source: {1}"
                                + "<br/>  - Stack Trace: {2}"
                                + "<br/>",
                                ex.Message,
                                ex.Source,
                                ex.StackTrace
                                ));
                        }
                    }
                }
                Response.Write(String.Format("<br /><a href=\"{0}\">Back</a>",
                    Request.Url.AbsolutePath
                    ));

                // Start the next scrape if all of them should be run
                if ((Request.QueryString["Done"] != null) && (scrapeID != null))
                {
                    int done = int.Parse(Request.QueryString["Done"]) + 1;
                    Response.AppendHeader("Refresh", "1;url=" + System.Text.RegularExpressions.Regex.Replace(Request.Url.PathAndQuery, "(?<=done\\=)\\d+", done.ToString(), System.Text.RegularExpressions.RegexOptions.IgnoreCase));
                }

                form1.Visible = false;
            }
            else
            {
                // Display the logs
                var logs = Functions.GetDatabaseDataContext()
                    .Logs
                    .OrderByDescending(l => l.UTC)
                    .Take(100)
                    .Select(l => new { l.UTC, l.IsError, l.Message });
                StringBuilder tableRows = new StringBuilder();
                foreach (var log in logs)
                {
                    tableRows.AppendLine(String.Format("<tr><td valign=\"top\">{0}</td><td valign=\"top\">{1}</td><td valign=\"top\">{2}</td></tr>",
                        log.UTC.ToString(),
                        log.IsError == 0 ? "Info" : "Error",
                        log.Message.Replace("\r\n", "<br/>").Replace("\r", "<br/>").Replace("\n", "<br/>")
                        ));
                }
                litLogTableRows.Text = tableRows.ToString();

                // Display the scrapes
                var scrapes = Functions.GetDatabaseDataContext()
                    .Scrapes
                    .OrderBy(s => s.Description)
                    .Select(s => new { s.ID, s.Description, League = s.League.Description });
                tableRows = new StringBuilder();
                foreach (var scrape in scrapes)
                {
                    string url = Functions.GetDatabaseDataContext()
                        .ScrapeSteps
                        .Where(ss => (ss.ScrapeID == scrape.ID)
                            && (ss.Action == (Byte)ScrapeFunctions.ScrapeAction.GetHTMLFromURL))
                        .Select(ss => ss.Parameter1)
                        .FirstOrDefault();
                    tableRows.AppendLine(String.Format("<tr><td>{0}</td><td>{1}</td><td><a href=\"{2}\">{2}</a></td><td><a href=\"Admin.aspx?ScrapeID={3}\">Run</a><td></tr>",
                        scrape.Description,
                        scrape.League,
                        url ?? "",
                        scrape.ID.ToString()
                        ));
                }
                litScrapeTableRows.Text = tableRows.ToString();
            }
        }

        protected void btnClearLog_Click(object sender, EventArgs e)
        {
            // Clear the logs
            using (MainDataClassesDataContext databaseDataContext = Functions.GetDatabaseDataContext())
            {
                databaseDataContext.ExecuteCommand("DELETE FROM Logs");
            }

            // Refresh the page
            Response.Redirect(Request.Url.ToString());
        }

        protected void btnRunAllScrapes_Click(object sender, EventArgs e)
        {
            // Refresh the page with the 'scrape all' query string passed
            Response.Redirect(String.Format("{0}?ScrapeID=All&Done=0",
                Request.Url.AbsolutePath
                ));
        }
    }
}
